package com.app.demo.service.impl;

import cn.hutool.core.util.StrUtil;
import com.app.cache.annotation.CollectionCacheEvict;
import com.app.cache.annotation.CollectionCacheable;
import com.app.demo.cache.enums.CacheEnum;
import com.app.demo.entity.User;
import com.app.demo.enums.LogModule;
import com.app.demo.mapper.UserMapper;
import com.app.demo.service.UserService;
import com.app.logrecord.annotation.LogRecord;
import com.app.logrecord.annotation.LogRecordModel;
import com.app.logrecord.enums.LogOperate;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@RequiredArgsConstructor
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @LogRecord(key = "#result.id",
            module = LogModule.Type.USER,
            desc = "新增用户",
            operateType = LogOperate.Type.SAVE)
    @CachePut(value = CacheEnum.Names.User, key = "#user.id")
    @Override
    public User insert(@LogRecordModel("user") User user) {
        return this.save(user) ? user : null;
    }

    @CacheEvict(value = CacheEnum.Names.User, key = "#id")
    @Override
    public void delete(Long id) {
        this.removeById(id);
    }

    @CollectionCacheEvict(value = CacheEnum.Names.User)
    @Override
    public void delete(List<Long> idList) {
        for (Long id : idList) {
            this.delete(id);
        }
    }

    @LogRecord(key = "#user.id",
            module = LogModule.Type.USER,
            desc = "更新用户",
            operateType = LogOperate.Type.UPDATE,
            method = "@userMapper.selectById(#root)")
    @CachePut(value = CacheEnum.Names.User, key = "#user.id")
    @Override
    public User edit(@LogRecordModel("user") User user) {
        return this.updateById(user) ? user : null;
    }

    @Cacheable(value = CacheEnum.Names.User, key = "#id"
            , unless = "#result == null"
            , condition = "#id != null")
    @Override
    public User getById(Long id) {
        return this.lambdaQuery().eq(User::getId, id).one();
    }

    @CollectionCacheable(value = CacheEnum.Names.User, timeout = 30, unit = TimeUnit.MINUTES)
    @Override
    public Page<User> pageList(User user, Long pageSize, Long pageNumber) {
        Page<User> page = new Page<User>(pageNumber, pageSize);
        return this.lambdaQuery().eq(StrUtil.isNotEmpty(user.getUsername()), User::getUsername, user.getUsername()).page(page);
    }

}
